package com.wheatek.wtklib.base.vm

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.wheatek.wtklib.net.LoadState
import com.wheatek.wtklib.net.exception.ExceptionUtils
import com.wheatek.wtklib.utils.LogUtil
import kotlinx.coroutines.*
import java.util.concurrent.atomic.AtomicInteger

open class BaseViewModel(app: Application) : AndroidViewModel(app) {

    // 加载状态
    val loadState = MutableLiveData<LoadState>()


    private var runningCount = AtomicInteger(0)

    /**
     * 是否正在请求网络
     */
    fun isStopped(): Boolean {
        return runningCount.get() == 0
    }

    /**
     * 后台静默加载,不显示loading
     */
    fun launchSilent(block: suspend CoroutineScope.() -> Unit) {
        launchRequest(1, block)
    }

    /**
     * 开始显示loading,结束关闭loading
     */
    fun launch(block: suspend CoroutineScope.() -> Unit) {
        launchRequest(block = block)
    }

    /**
     * @param loadingType 0: 默认 1: silent
     */
    private fun launchRequest(loadingType: Int = 0, block: suspend CoroutineScope.() -> Unit) {
        viewModelScope.launch(
            CoroutineExceptionHandler { _, throwable ->
                run {
                    // handle error
                    val error = ExceptionUtils.parseException(throwable)
//                    if (BuildConfig.DEBUG) {
//                        LogUtil.LOGE("网络请求异常：$throwable")
//                    }
                    if (loadingType == 0) {
                        loadState.value = LoadState.Error(error)
                        if (runningCount.get() > 0) {
                            runningCount.getAndDecrement()
                        }
                        LogUtil.LOGD("runningCount - : $runningCount")
                        loadState.value = LoadState.Finish
                    }
                }
            }
        ) {
            try {
                if (loadingType == 0) {
                    runningCount.getAndIncrement()
                    LogUtil.LOGD("runningCount + : $runningCount")
                    loadState.value = LoadState.Start()
                }
                withContext(Dispatchers.IO) {
                    block.invoke(this)
                }
            } finally {
                if (loadingType == 0) {
                    if (runningCount.get() > 0) {
                        runningCount.getAndDecrement()
                    }
                    LogUtil.LOGD("runningCount - : $runningCount")
                    loadState.value = LoadState.Finish
                }
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        runningCount.getAndSet(0)
    }
}